package net.findkrypton.entity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.input.MouseButton;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import net.findkrypton.GameInfo;
import net.findkrypton.enume.CenterButtonState;
import net.findkrypton.event.RunningStateEvent;
import net.findkrypton.po.SaveFile;
import net.jumpengine.bean.Base;
import net.jumpengine.bean.ClickBase;
import net.jumpengine.inter.IAction;
import net.jumpengine.util.UComm;

/**
  * 发现氪金的主体实现部分
 * <br /><br />
 * <b>作者:&nbsp;</b>张天文 <br />
 * <b>日期:&nbsp;</b>2020年3月7日 下午9:36:28<br />
 * @date
 */
public class ArrayBase extends ClickBase{
	protected int[] array;
	protected Font f=new Font("黑体",18);
	protected Color[] colors=new Color[] {
		Color.rgb(253,236,185),Color.rgb(234,174,228),Color.rgb(182,247,149),Color.rgb(109,191,188),
		Color.rgb(201,102,117),Color.rgb(190,242,250),Color.rgb(234,187,110),Color.rgb(151,247,126)
	};
	private GameInfo info;
	private Image box,krypton,flag;
	private int num=0,one,kcount,cache,cacheArr[]=new int[8];
	private boolean loser=false;
	private RunningStateEvent event;
	private List<Integer> list=new ArrayList<Integer>();
	private boolean back=true;
	private MouseButton mouse;
	
	public ArrayBase(GameInfo info,Image box,Image krypton,Image flag) {
		super(info.getX(), info.getY(), info.getWidth(), info.getHeight());
		array=info.getArray();
		this.info=info;
		this.box=box;
		this.krypton=krypton;
		this.flag=flag;
		one=info.getOne();
		kcount=info.getKcount()-1;
		
		//UComm.array(array);
		
		action=new IAction() {
			private int cx,cy,ind,tmp;
			private boolean isUse=false;
			
			@Override
			public void handle(int mx, int my, MouseButton button, Base base) {
				if(button==MouseButton.MIDDLE) {
					for(int i=0;i<array.length;i++) {
						tmp=array[i];
						if(tmp>=18)array[i]=tmp-20;
					}
					return;
				}
				if(loser)return;
				if(mx<x ||mx>x+width || my<y || my>y+height)return;
				cx= (mx-x)/one;
				cy= (my-y)/one;
				ind=cx+cy*info.getHcount();
				if(ind<0 || ind>=array.length)return;
				tmp=array[ind];
				cache=ind;
				mouse=button;
				
				if(button==MouseButton.SECONDARY) {
					if(tmp>=38 && tmp<=48) {
						array[ind]+=20;
					}else if(tmp==0) {
						openOne(ind,true);
					}else if(tmp>=1 && tmp<=8) {
						//M.l().debug(ArrayBase.class,"[action.handle]ind=",ind," count=",info.countOne(ind,-2,18,58)," array[]=",array[ind]);
						if(info.countOne(ind,58,60,61,62,63,64,65,66,67,68)==tmp) {
							makeOne(ind);
							check(ind);
						}
					}else if(tmp>=18 && tmp<=28) {
						array[ind]+=40;
						kcount--;
						event.getNumber().setVal(kcount);
					}
					return;
				}
				isUse=false;
				if(tmp>=38 && tmp<=48) {
					array[ind]-=20;
					isUse=true;
				}else if(tmp>=58) {
					array[ind]-=20;
					kcount++;
					event.getNumber().setVal(kcount);
					isUse=true;
				}
				if(isUse)return;
				
				if(tmp>=18) {
					array[ind]=tmp-20;
					if(array[ind]==-2) {
						setLoser();
						return;
					}
				}
				if(tmp>=20)openOne(ind,true);
			}
		};
		
		int tmp,count=array.length-1;
		while(true) {
			tmp=UComm.rnd(0, count);
			if(array[tmp]==20) {
				array[tmp]=0;
				openOne(tmp,true);
				break;
			}
		}
	}

	@Override
	public void draw(GraphicsContext g) {
		g.setFont(f);
		for(int i=0;i<info.getHcount();i++) {
			for(int j=0;j<info.getVcount();j++) {
				num=array[i+j*info.getHcount()];
				if(num==-2) {
					g.drawImage(krypton, i*one+x, j*one+y);
				}else if(num>0 && num<9){
					g.setFill(colors[num]);
					g.fillText(num+"", i*one+7+x, j*one+2+y);
				}else if(num>=9 && num<=28) {
					g.drawImage(box, i*one+x, j*one+y);
				}else if(num>=38 && num<=48) {
					g.setFill(Color.BLACK);
					g.drawImage(box, i*one+x, j*one+y);
					g.fillText("?", i*one+7+x, j*one+2+y);
				}else if(num>=58) {
					g.drawImage(box, i*one+x, j*one+y);
					g.drawImage(flag, i*one+x, j*one+y);
				}
				g.setStroke(colors[Math.abs(num%8)]);
				if(num<9) {
					if(i==0 || j==0) {
						g.strokeLine(i*one+x, j*one+y, i*one+x, j*one+y+one);
						g.strokeLine(i*one+x, j*one+y, i*one+x+one, j*one+y);
						
					}
					g.strokeLine(i*one+x+one, j*one+y, i*one+x+one, j*one+y+one);
					g.strokeLine(i*one+x, j*one+y+one, i*one+x+one, j*one+y+one);
				}
			}
		}
	}
	
	private void check(int index) {
		if(info.countOne(index, -2)>0) {
			setLoser();
		}
	}
	
	private void setLoser() {
		loser=true;
		event.getImageState().setState(CenterButtonState.loser);
		event.getTime().setAble(false);
		if(back)event.getIcon().setVisible(true);
	}
	
	public void reset() {
		info.reset();
		array=info.getArray();
		event.getTime().setAble(true);
		event.getTime().reset();
		event.getNumber().setVal(info.getKcount());
		event.getImageState().setState(CenterButtonState.nomal);
		event.getIcon().setVisible(false);
		loser=false;
		x=info.getX();
		y=info.getY();
		width=info.getWidth();
		height=info.getHeight();
		kcount=info.getKcount();
		back=true;
		
		int tmp,count=array.length-1;
		while(true) {
			tmp=UComm.rnd(0, count);
			if(array[tmp]==20) {
				array[tmp]=0;
				openOne(tmp,true);
				break;
			}
		}
	}
	
	public void reload(SaveFile save,int[] ints) {
		info.reload(save, ints);
		array=info.getArray();
		event.getTime().setAble(true);
		event.getTime().setVal(save.getUseTime());
		event.getNumber().setVal(save.getNoFlag());
		event.getImageState().setState(CenterButtonState.nomal);
		event.getIcon().setVisible(false);
		loser=false;
		x=info.getX();
		y=info.getY();
		height=info.getHeight();
		kcount=info.getKcount();
		back=true;
	}
	
	public void back() {
		loser=false;
		event.getImageState().setState(CenterButtonState.nomal);
		event.getTime().setAble(true);
		if(mouse==MouseButton.PRIMARY) {
			array[cache]+=20;
			kcount++;
			event.getNumber().setVal(kcount);
		}else if(mouse==MouseButton.SECONDARY) {
			int count=info.countOne(cache, -2);
			
			for(int n:cacheArr)if(n>=0)array[n]+=20;
			kcount+=count;
			event.getNumber().setVal(kcount);
		}
		back=false;
		event.getIcon().setVisible(false);
	}
	
	/**
	  * 将周围8格,没有氪金的格子展开
	 * @param index array数组的序号
	 */
	private void openOne(int index,boolean more) {
		int hcount=info.getHcount(),tmp,val;
		if(more)list.clear();
		
		if(index % hcount !=0) {
			tmp=index-hcount-1;
			val=kill(tmp,19,49);
			if(val==0 && more)list.add(tmp);
		}
		tmp=index-hcount;
		val=kill(tmp,19,49);
		if(val==0 && more)list.add(tmp);
		if((index-(hcount-1)) % hcount !=0) {
			tmp=index-hcount+1;
			val=kill(tmp,19,49);
			if(val==0 && more)list.add(tmp);
		}
		
		if(index % hcount !=0) {
			tmp=index-1;
			val=kill(tmp,19,49);
			if(val==0 && more)list.add(tmp);
		}
		if((index-(hcount-1)) % hcount !=0) {
			tmp=index+1;
			val=kill(tmp,19,49);
			if(val==0 && more)list.add(tmp);
		}
		
		if(index % hcount !=0) {
			tmp=index+hcount-1;
			val=kill(tmp,19,49);
			if(val==0 && more)list.add(tmp);
		}
		
		tmp=index+hcount;
		val=kill(tmp,19,49);
		if(val==0 && more)list.add(tmp);
		if((index-(hcount-1)) % hcount !=0) {
			tmp=index+hcount+1;
			val=kill(tmp,19,49);
			if(val==0 && more)list.add(tmp);
		}
		
		if(!more)return;
		for(Integer i:list)openOne(i,false);
	}
	
	/**
	  * 将周围8格除了插旗的,其他强行展开
	 * @param index array数组的序号
	 */
	private void makeOne(int index) {
		int hcount=info.getHcount(),tmp,val;
		Arrays.fill(cacheArr, -1);
		
		if(index % hcount !=0) {
			tmp=index-hcount-1;
			val=kill(tmp,-1,58);
			if(val==0)openOne(tmp,false);
			if(val==-2)cacheArr[0]=tmp;
		}
		tmp=index-hcount;
		val=kill(tmp,-1,58);
		if(val==0)openOne(tmp,false);
		if(val==-2)cacheArr[1]=tmp;
		if((index-(hcount-1)) % hcount !=0) {
			tmp=index-hcount+1;
			val=kill(tmp,-1,58);
			if(val==0)openOne(tmp,false);
			if(val==-2)cacheArr[2]=tmp;
		}
		if(index % hcount !=0) {
			tmp=index-1;
			val=kill(tmp,-1,58);
			if(val==0)openOne(tmp,false);
			if(val==-2)cacheArr[3]=tmp;
		}
		if((index-(hcount-1)) % hcount !=0) {
			tmp=index+1;
			val=kill(tmp,-1,58);
			if(val==0)openOne(tmp,false);
			if(val==-2)cacheArr[4]=tmp;
		}
		
		if(index % hcount !=0) {
			tmp=index+hcount-1;
			val=kill(tmp,-1,58);
			if(val==0)openOne(tmp,false);
			if(val==-2)cacheArr[5]=tmp;
		}
		tmp=index+hcount;
		val=kill(tmp,-1,58);
		if(val==0)openOne(tmp,false);
		if(val==-2)cacheArr[6]=tmp;
		if((index-(hcount-1)) % hcount !=0) {
			tmp=index+hcount+1;
			val=kill(tmp,-1,58);
			if(val==0)openOne(tmp,false);
			if(val==-2)cacheArr[7]=tmp;
		}
	}
	
	private int val;
	/**
	  * 如果符合条件,array数组中ind位置的数据减20(即展开一层)
	 * @param ind array数组的序号
	 * @param min 大于等于min,小于0不比较
	 * @param max 小于max,小于0不比较
	 */
	private int kill(int ind,int min,int max) {
		if(ind>=0 && ind<array.length) {
			val=array[ind];
			if(min>=0) {
				if(max>=0) {
					if(val>=min && val<max && val>=18)array[ind]-=20;
				}else {
					if(val>=min && val>=18)array[ind]-=20;
				}
			}else {
				if(max>=0) {
					if(val<max && val>=18)array[ind]-=20;
				}else {
					array[ind]-=20;
				}
			}
			return array[ind];
		}
		return -1;
	}

	public boolean isLoser() {
		return loser;
	}

	public void setLoser(boolean loser) {
		this.loser = loser;
	}

	public void setEvent(RunningStateEvent event) {
		this.event = event;
	}

	public int[] getArray() {
		return array;
	}

	public void setArray(int[] array) {
		this.array = array;
	}

	public GameInfo getInfo() {
		return info;
	}

	public void setInfo(GameInfo info) {
		this.info = info;
	}

	public int getKcount() {
		return kcount;
	}

	public void setKcount(int kcount) {
		this.kcount = kcount;
	}

	public RunningStateEvent getEvent() {
		return event;
	}
}
